package train;

import java.util.ArrayList;
import java.util.Observable;

import capteurs.CPresence;
import capteurs.CVitesse;
import capteurs.Capteur;

import rails.JAiguillage;
import rails.JButee;
import rails.JSimple;
import rails.Rail;
import regulation.Regulation;
import regulation.RegulationT1;
import semaphores.*;


public class ReseauFerroviaire extends Observable {

	/**
	 * An array list of train and rail
	 */
	private ArrayList<Train> trainList;
	
	private ArrayList<Rail> railList;
	
	private ArrayList<Regulation> regList;
	
	private boolean continu;
	
	public ReseauFerroviaire () {
		trainList = new ArrayList<Train>();
		railList = new ArrayList<Rail>();
		regList = new ArrayList<Regulation>();
		continu = true;
	}
	
	/**
	 * Add a new rail to the list
	 * @param newRail
	 */
	public void addRail(Rail newRail){		
		this.railList.add(newRail);		
	}
	
	/**
	 *  Add a new train to the list
	 * @param newTrain
	 */
	public void addTrain (Train newTrain){		
		this.trainList.add(newTrain);
		this.addObserver(newTrain);
	}
	
	public void addReg (Regulation newReg){		
		this.regList.add(newReg);
	}
	
	public Rail getRail(int i) {
		return railList.get(i);
	}
	
	public Regulation getReg(int i) {
		return regList.get(i);
	}
	
	public Train getTrain(int i) {
		return trainList.get(i);
	}
	
	public void start_clock_cycle() {
		continu = true;
		
		while(continu) {
			setChanged();
			notifyObservers();
			System.out.println("Train " + trainList.get(0).getId() + " sur rail " + trainList.get(0).getRail() + " au tronçon " + trainList.get(0).getCurrPosOnRail());
			try {
				Thread.sleep(1000);
			}
			catch(InterruptedException E) {
				E.printStackTrace();
			}
		}
	}
	
	public void stop_clock_cycle() {
		continu = false;
	}
	
	public static void main(String[] args) {
		ReseauFerroviaire reseau = new ReseauFerroviaire();
		JButee tmpButee;
		JSimple tmpSimple;
		JSimple tmpSimple2;
		JAiguillage tmpAiguillage;
		Bicolore tmpBicolore;
		Train tmpTrain;
		CVitesse tmpVitesse;
		CPresence tmpPresence;
		Regulation tmpRegulation;
		Rail tmpRail;
		
		//Pour commencer simple, une ligne de rails.
		/*tmpButee = new JButee();
		tmpSimple = new JSimple();
		tmpRail = new Rail(15, tmpButee, tmpSimple);
		tmpButee.setRail(tmpRail);
		tmpSimple.setRail1(tmpRail);
		reseau.addRail(tmpRail);
		
		tmpSimple2 = new JSimple();
		tmpRail = new Rail(42, tmpSimple, tmpSimple2);
		tmpSimple.setRail2(tmpRail);
		tmpSimple2.setRail1(tmpRail);
		reseau.addRail(tmpRail);
		
		tmpButee = new JButee();
		tmpRail = new Rail(4, tmpSimple2, tmpButee);
		tmpButee.setRail(tmpRail);
		tmpSimple2.setRail2(tmpRail);
		reseau.addRail(tmpRail);
		
		reseau.addTrain(new Train(5, 3, true, reseau.getRail(1)));
		reseau.getRail(1).ajoutTrain(reseau.getTrain(0));*/
		
		//Une ligne avec un semaphore Rouge
		tmpButee = new JButee();
		tmpSimple = new JSimple();
		tmpRail = new Rail(15, tmpButee, tmpSimple);
		tmpButee.setRail(tmpRail);
		tmpSimple.setRail1(tmpRail);
		reseau.addRail(tmpRail);
		
		tmpSimple2 = new JSimple();
		tmpRail = new Rail(42, tmpSimple, tmpSimple2);
		tmpSimple.setRail2(tmpRail);
		tmpSimple2.setRail1(tmpRail);
		tmpBicolore = new Bicolore();
		tmpBicolore.setState(Rouge.getInstance());
		tmpRail.setSemaphore(tmpBicolore, 2);
		reseau.addRail(tmpRail);
		
		tmpButee = new JButee();
		tmpRail = new Rail(4, tmpSimple2, tmpButee);
		tmpButee.setRail(tmpRail);
		tmpSimple2.setRail2(tmpRail);
		reseau.addRail(tmpRail);
		
		reseau.addTrain(new Train(5, 3, true, reseau.getRail(1)));
		reseau.getRail(1).ajoutTrain(reseau.getTrain(0));
		
		//Réseau simple mais plus complexe avec Aiguillage, permet de tester les différents cas de sortie.
		/*tmpButee = new JButee();
		tmpSimple = new JSimple();
		tmpRail = new Rail(9, tmpButee, tmpSimple);
		tmpButee.setRail(tmpRail);
		tmpSimple.setRail1(tmpRail);
		reseau.addRail(tmpRail);
		
		tmpAiguillage = new JAiguillage();
		tmpRail = new Rail(21, tmpSimple, tmpAiguillage);
		tmpSimple.setRail2(tmpRail);
		reseau.addRail(tmpRail);
		
		ArrayList<Rail> list1, list2;
		list1 = new ArrayList<Rail>();
		list2 = new ArrayList<Rail>();
		list1.add(tmpRail);
		tmpButee = new JButee();
		list1.add(new Rail(8, tmpButee, tmpAiguillage));
		tmpButee.setRail(list1.get(1));
		tmpAiguillage.setAval(list1);
		reseau.addRail(list1.get(1));
		
		tmpButee = new JButee();
		list2.add(new Rail(12, tmpAiguillage, tmpButee));
		tmpButee.setRail(list2.get(0));
		reseau.addRail(list2.get(0));
		
		tmpButee = new JButee();
		list2.add(new Rail(42, tmpAiguillage, tmpButee));
		tmpButee.setRail(list2.get(1));
		reseau.addRail(list2.get(1));
		
		tmpButee = new JButee();
		list2.add(new Rail(2, tmpAiguillage, tmpButee));
		tmpButee.setRail(list2.get(2));
		reseau.addRail(list2.get(2));
		tmpAiguillage.setAmont(list2);
		
		reseau.addTrain(new Train(5, 3, true, reseau.getRail(1)));
		reseau.getRail(1).ajoutTrain(reseau.getTrain(0));*/
		
		//Même exemple avec Régulation, capteur et touti quanti lolz
		/*tmpButee = new JButee();
		tmpSimple = new JSimple();
		tmpRail = new Rail(9, tmpButee, tmpSimple);
		tmpButee.setRail(tmpRail);
		tmpSimple.setRail1(tmpRail);
		reseau.addRail(tmpRail);
		
		tmpAiguillage = new JAiguillage();
		tmpRail = new Rail(21, tmpSimple, tmpAiguillage);
		tmpSimple.setRail2(tmpRail);
		reseau.addRail(tmpRail);
		
		ArrayList<Rail> list1, list2;
		list1 = new ArrayList<Rail>();
		list2 = new ArrayList<Rail>();
		list1.add(tmpRail);
		tmpButee = new JButee();
		list1.add(new Rail(8, tmpButee, tmpAiguillage));
		tmpButee.setRail(list1.get(1));
		tmpAiguillage.setAval(list1);
		reseau.addRail(list1.get(1));
		
		tmpButee = new JButee();
		list2.add(new Rail(12, tmpAiguillage, tmpButee));
		tmpButee.setRail(list2.get(0));
		reseau.addRail(list2.get(0));
		
		tmpButee = new JButee();
		list2.add(new Rail(42, tmpAiguillage, tmpButee));
		tmpButee.setRail(list2.get(1));
		reseau.addRail(list2.get(1));
		
		tmpButee = new JButee();
		list2.add(new Rail(2, tmpAiguillage, tmpButee));
		tmpButee.setRail(list2.get(2));
		reseau.addRail(list2.get(2));
		tmpAiguillage.setAmont(list2);
		
		CPresence[] CTable = new CPresence[2];
		CTable[0] = new CPresence(reseau.getRail(1), 15);
		CTable[1] = new CPresence(reseau.getRail(2), 6);
		reseau.addObserver(CTable[0]);
		reseau.addObserver(CTable[1]);
		
		Bicolore[] BTable = new Bicolore[2];
		BTable[0] = new Bicolore();
		BTable[1] = new Bicolore();
		reseau.getRail(1).setSemaphore(BTable[0], 2);
		reseau.getRail(2).setSemaphore(BTable[1], 2);
		reseau.addReg(new RegulationT1());
		((RegulationT1)(reseau.getReg(0))).setCapteurs(CTable);
		((RegulationT1)(reseau.getReg(0))).setBicolore(BTable);
		((RegulationT1)(reseau.getReg(0))).setAguillage(tmpAiguillage);
		CTable[0].ajouter_observer(reseau.getReg(0));
		CTable[1].ajouter_observer(reseau.getReg(0));
		
		reseau.addTrain(new Train(5, 2, true, reseau.getRail(1)));
		reseau.getRail(1).ajoutTrain(reseau.getTrain(0));*/
		
		reseau.start_clock_cycle();
	}
}
